#include "async_io.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/epoll.h>

#define MAX_EVENTS 10

void async_read(int fd, char *buffer, size_t buffer_size, AsyncCallback callback) {
    static struct epoll_event events[MAX_EVENTS];  // 静态变量
    int epoll_fd = epoll_create1(0);
    if (epoll_fd == -1) {
        perror("epoll_create1");
        return;
    }

    struct epoll_event event;
    event.events = EPOLLIN | EPOLLET;
    event.data.fd = fd;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event) == -1) {
        perror("epoll_ctl");
        return;
    }

    while (1) {
        int num_ready = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
        if (num_ready == -1) {
            perror("epoll_wait");
            return;
        }

        for (int i = 0; i < num_ready; ++i) {
            if (events[i].data.fd == fd) {
                ssize_t num_bytes = read(fd, buffer, buffer_size);
                if (num_bytes > 0) {
                    callback(fd, buffer, num_bytes);
                } else if (num_bytes == 0) {
                    // 客户端关闭连接
                    printf("Client closed the connection.\n");
                } else if (errno != EAGAIN && errno != EWOULDBLOCK) {
                    // 读取错误
                    perror("read");
                }
            }
        }
    }
}

void async_write(int fd, const char *buffer, size_t buffer_size, AsyncCallback callback) {
    static struct epoll_event events[MAX_EVENTS];  // 静态变量
    int epoll_fd = epoll_create1(0);
    if (epoll_fd == -1) {
        perror("epoll_create1");
        return;
    }

    struct epoll_event event;
    event.events = EPOLLOUT | EPOLLET;
    event.data.fd = fd;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event) == -1) {
        perror("epoll_ctl");
        return;
    }

    while (1) {
        int num_ready = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
        if (num_ready == -1) {
            perror("epoll_wait");
            return;
        }

        for (int i = 0; i < num_ready; ++i) {
            if (events[i].data.fd == fd) {
                ssize_t num_bytes = write(fd, buffer, buffer_size);
                if (num_bytes > 0) {
                    callback(fd, buffer, num_bytes);
                } else if (num_bytes == 0) {
                    // 客户端关闭连接
                    printf("Client closed the connection.\n");
                } else if (errno != EAGAIN && errno != EWOULDBLOCK) {
                    // 写入错误
                    perror("write");
                }
            }
        }
    }
}
